/*
*
* ████████╗░█████╗░███████╗██████╗░░█████╗░
* ╚══██╔══╝██╔══██╗██╔════╝██╔══██╗██╔══██╗
* ░░░██║░░░██║░░██║█████╗░░██████╦╝███████║
* ░░░██║░░░██║░░██║██╔══╝░░██╔══██╗██╔══██║
* ░░░██║░░░╚█████╔╝██║░░░░░██████╦╝██║░░██║
* ░░░╚═╝░░░░╚════╝░╚═╝░░░░░╚═════╝░╚═╝░░╚═╝
* 
*  :: 九方通逊-Henry ::   Copyright©2020 tofba.com  
* 
*/
package com.lmexpress.service.impl;

import java.io.File;
import java.net.URL;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.lmexpress.enums.ApiCredential;
import com.lmexpress.enums.ApiOrderError;
import com.lmexpress.enums.LabelFormat;
import com.lmexpress.enums.LabelSuffix;
import com.lmexpress.orm.kts.Address;
import com.lmexpress.orm.kts.KTSLableParm;
import com.lmexpress.orm.kts.KTSOrder;
import com.lmexpress.orm.kts.KTSProduct;
import com.lmexpress.orm.kts.Parcel;
import com.lmexpress.orm.kts.SenderOrReceiver;
import com.lmexpress.orm.openapi.ExpressOrderApi;
import com.lmexpress.orm.openapi.OrderInvoice;
import com.lmexpress.orm.rest.ApiLabelResponse;
import com.lmexpress.orm.rest.ApiOrderResponse;
import com.lmexpress.service.ApiService;
import com.lmexpress.util.ApiUtil;
import com.lmexpress.util.HttpClientPoolUtil;
import com.lmexpress.util.HttpClientResult;

/**
 * 
 * <顺丰喀秋莎.>
 * 
 * @author Henry(fba02)
 * @version [版本号, 2020-12-09]
 * @see [相关类/方法]
 * @since [产品/模块版本]
 */
public class KTSClient implements ApiService {
	private Logger LOGGER = LoggerFactory.getLogger(KTSClient.class);
	private final static String SUCCESS = "1";

	@Override
	public ApiOrderResponse preProcessCreateOrder(ExpressOrderApi expressOrderApi) {
		return null;
	}

	@Override
	public String mapping(ExpressOrderApi expressOrderApi) {
		Map<String, String> apiCredentials = expressOrderApi.getApiCredentials();
		KTSOrder ktsOrder = new KTSOrder();
		// KTS系统提供 的识别码
		ktsOrder.setApi_username(apiCredentials.get(ApiCredential.KTS_API_USERNAME.getKey()));
		ktsOrder.setApi_key(apiCredentials.get(ApiCredential.KTS_API_KEY.getKey()));
		// 客户参考号
		ktsOrder.setOrder_sn(expressOrderApi.getCustomerInvoiceCode());
		// 客户编码
		ktsOrder.setPlatform_merchant_id(expressOrderApi.getCustomerCode());
		// 快件类型/128/卢邮小包
		ktsOrder.setExpress_type(apiCredentials.get(ApiCredential.KTS_EXPRESS_TYPE.getKey()));
		// 发件人信息
		SenderOrReceiver sender = new SenderOrReceiver();
		sender.setCountry_code(DEFAULT_SHIPPER_COUNTRY_CODE);
		sender.setCompany(apiCredentials.get(ApiCredential.KTS_DEFAULT_SENDER_COMPANY.getKey()));
		sender.setPhone(apiCredentials.get(ApiCredential.KTS_DEFAULT_SENDER_PHONE.getKey()));
		sender.setMobile(apiCredentials.get(ApiCredential.KTS_DEFAULT_SENDER_MOBILE.getKey()));
		sender.setZipcode(apiCredentials.get(ApiCredential.KTS_DEFAULT_SENDER_ZIPCODE.getKey()));
		sender.setEmail(apiCredentials.get(ApiCredential.KTS_DEFAULT_SENDER_EMAIL.getKey()));
		Address addresss = new Address();
		addresss.setProvince(apiCredentials.get(ApiCredential.KTS_DEFAULT_SENDER_PROVINCE.getKey()));
		addresss.setCity(apiCredentials.get(ApiCredential.KTS_DEFAULT_SENDER_CITY.getKey()));
		addresss.setDistrict(apiCredentials.get(ApiCredential.KTS_DEFAULT_SENDER_DISTRICT.getKey()));
		addresss.setStreet_address(apiCredentials.get(ApiCredential.KTS_DEFAULT_SENDER_STREET_ADDRESS.getKey()));
		addresss.setName(apiCredentials.get(ApiCredential.KTS_DEFAULT_SENDER_NAME.getKey()));
		sender.setAddress(addresss);
		ktsOrder.setSender(sender);
		// 收件人
		SenderOrReceiver receiver = new SenderOrReceiver();
		// 国家二字代码
		receiver.setCountry_code(expressOrderApi.getCountryCode());
		// 公司
		receiver.setCompany(expressOrderApi.getConsigneeCompanyName());
		receiver.setPhone(expressOrderApi.getConsigneeTelephone());
		receiver.setMobile(expressOrderApi.getConsigneeMobile());
		receiver.setZipcode(expressOrderApi.getConsigneePostCode());
		receiver.setEmail(expressOrderApi.getConsigneeEmail());
		Address addressr = new Address();
		addressr.setProvince(expressOrderApi.getConsigneeState());
		addressr.setCity(expressOrderApi.getConsigneeCity());
		// 收件人没有区
		addressr.setDistrict(null);
		addressr.setStreet_address(expressOrderApi.getConsigneeAddress() + expressOrderApi.getConsigneeAddress2());
		addressr.setName(expressOrderApi.getConsigneeName());
		receiver.setAddress(addressr);
		// 放入收件人
		ktsOrder.setReceiver(receiver);
		// 包裹信息
		Parcel parcel = new Parcel();
		parcel.setWeight(expressOrderApi.getWeight());
		// 长宽高 默认
		parcel.setLength(15D);
		parcel.setWidth(10D);
		parcel.setHeight(5D);
		// 默认不带电
		parcel.setHas_battery(false);
		// 默认 不是液体
		parcel.setHas_liquid(false);
		// 货物下面的有SKU信息
		List<KTSProduct> ktsProducts = new ArrayList<KTSProduct>();
		// SKU信息
		List<OrderInvoice> orderInvoices = expressOrderApi.getOrderInvoices();
		DecimalFormat decimalFormat = new DecimalFormat("0.0000");
		double invoiceAmountCount = 0D;
		KTSProduct ktsProduct = null;
		for (int i = 0; i < orderInvoices.size(); i++) {
			OrderInvoice orderInvoice = orderInvoices.get(i);
			ktsProduct = new KTSProduct();
			ktsProduct.setDescription_en(orderInvoice.getSkuNameEn());
			ktsProduct.setDescription_cn(orderInvoice.getSkuNameCn() == null ? orderInvoice.getSkuCode() : orderInvoice.getSkuNameCn());
			ktsProduct.setWeight(orderInvoice.getInvoiceWeight());
			ktsProduct.setQuantity(orderInvoice.getInvoicePcs());
			ktsProduct.setDeclare_value(orderInvoice.getInvoiceAmount());
			ktsProduct.setHs_code(orderInvoice.getHsCode());
			ktsProduct.setProduct_url(orderInvoice.getSalesLink());
			// 备注
			ktsProduct.setPicking_info(orderInvoice.getSkuNameCn() + "*" + orderInvoice.getInvoicePcs());
			invoiceAmountCount = invoiceAmountCount + orderInvoice.getInvoiceAmount();
			ktsProducts.add(ktsProduct);
		}
		// 申报总价值
		parcel.setDeclare_value(Double.parseDouble(decimalFormat.format(invoiceAmountCount)));
		// 放入货物信息
		parcel.setProduct_list(ktsProducts);
		// 放入货物信息
		ktsOrder.setParcel(parcel);
		return new Gson().toJson(ktsOrder);
	}

	@Override
	public ApiOrderResponse createOrder(ExpressOrderApi expressOrderApi) {
		try {
			String orderJson = mapping(expressOrderApi);
			LOGGER.info("kts.shipment.request:{}", orderJson);
			HttpClientResult httpClientResult = HttpClientPoolUtil.doPost(ApiCredential.KTS_CREATE_ORDER.getValue(), HttpClientPoolUtil.setJsonHeader(), orderJson);
			if (null == httpClientResult || httpClientResult != null && StringUtils.isBlank(httpClientResult.getContent())) {
				return new ApiOrderResponse(false, null, ApiOrderError.SERVICE_NO_DATA_RETURN.getMessage(), true, null);
			}
			String response = httpClientResult.getContent();
			LOGGER.info("kts.shipment.response:{}", response);
			// {\"agent_mailno\":\"UL194242859EE\",\"code\":\"1\",\"direction_code\":\"9HP-AU\",\"message\":\"success\",\"order_sn\":\"COT004633153019AUS\",\"tracking_no\":\"GL001318461514\"}
			Map<String, String> responseMap = new Gson().fromJson(response, new TypeToken<Map<String, String>>() {
			}.getType());
			if (null == responseMap) {
				return new ApiOrderResponse(false, null, ApiOrderError.SERVICE_NO_DATA_RETURN.getMessage(), true, null);
			}
			String code = responseMap.get("code");
			// 下单成功
			if (!SUCCESS.equals(code)) {
				String message = responseMap.get("message");
				return new ApiOrderResponse(false, null, message, response);
			}
			ApiOrderResponse apiOrderResponse = new ApiOrderResponse();
			apiOrderResponse.setSuccess(true);
			apiOrderResponse.setReferenceNo(expressOrderApi.getCustomerInvoiceCode());
			apiOrderResponse.setTrackNumber(responseMap.get("agent_mailno"));
			apiOrderResponse.setThirdPartyorderNo(responseMap.get("tracking_no"));
			ApiLabelResponse apiLabelResponse = label(expressOrderApi.getCustomerInvoiceCode(), responseMap.get("tracking_no"), expressOrderApi.getApiCredentials());
			if (null != apiLabelResponse) {
				apiOrderResponse.setLabelUrl(apiLabelResponse.getLabelPath());
				apiOrderResponse.setLmLabelUrl(apiLabelResponse.getRelativePath());
			}
			apiOrderResponse.setOriginalResponse(response);
			return apiOrderResponse;
		} catch (Exception e) {
			LOGGER.error("kts.shipment.exception", e);
			return new ApiOrderResponse(false, null, ApiOrderError.CREATE_ORDER_EXCEPTION.getMessage(), false, e.getMessage());
		}
	}

	@Override
	public ApiLabelResponse label(String trackNumber, Map<String, String> configureMap) {
		return null;
	}

	@Override
	public ApiLabelResponse labelRender(String trackNumber, ExpressOrderApi expressOrderApi) {
		return null;
	}

	@Override
	public void tracking(String trackNumber, Map<String, String> configureMap) {

	}

	@Override
	public String trackNumber(String code, Map<String, String> configureMap) {
		return null;
	}

	@Override
	public ApiLabelResponse label(String referenceNo, String trackNumber, Map<String, String> configureMap) {
		KTSLableParm kTSLableParm = new KTSLableParm();
		kTSLableParm.setApi_username(configureMap.get(ApiCredential.KTS_API_USERNAME.getKey()));
		kTSLableParm.setApi_key(configureMap.get(ApiCredential.KTS_API_KEY.getKey()));
		// 获取面单需要两个客户参考号
		kTSLableParm.setOrder_sn(referenceNo);
		// 顺丰的订单号
		kTSLableParm.setTracking_no(trackNumber);
		try {
			Gson gson = new Gson();
			// 请求面单接口
			HttpClientResult httpClientResult = HttpClientPoolUtil.doPost(ApiCredential.KTS_LABEL.getValue(), HttpClientPoolUtil.setJsonHeader(), gson.toJson(kTSLableParm));
			LOGGER.info("kts.lable.response:{}", httpClientResult);
			if (null == httpClientResult) {
				return new ApiLabelResponse(null, null);
			}
			// 有返回值
			String ktsGetLableResponse = httpClientResult.getContent();
			LOGGER.info("kts.get.lable.response:{}", ktsGetLableResponse);
			// {\"code\":\"1\",\"label_url\":\"http://yunmiandan-1251224359.cos.ap-shanghai.myqcloud.com/GL001318461514.pdf\",\"message\":\"success\",\"order_sn\":\"COT004633153019AUS\",\"tracking_no\":\"GL001318461514\"}
			Map<String, String> responseMap = gson.fromJson(ktsGetLableResponse, new TypeToken<Map<String, String>>() {
			}.getType());
			if (null == responseMap) {
				return new ApiLabelResponse(trackNumber, null);
			}
			String code = responseMap.get("code");
			if (!SUCCESS.equals(code)) {
				return new ApiLabelResponse(trackNumber, null);
			}
			String label_url = responseMap.get("label_url");
			// String order_sn = responseMap.get("order_sn");
			// String tracking_no = responseMap.get("tracking_no");
			String pdfName = trackNumber + LabelSuffix.PDF.getSuffix();
			String centrePath = ApiUtil.getCurrentDay() + File.separator;
			String relativePath = DEFAULT_LABEL_FOLDER + File.separator + centrePath;
			String folderPath = DEFAULT_LABEL_ROOT + relativePath;
			if (!new File(folderPath).exists()) {
				new File(folderPath).mkdirs();
			}
			String fileUrl = folderPath + pdfName;
			ApiLabelResponse apiLabelResponse = new ApiLabelResponse();
			apiLabelResponse.setBarCode(trackNumber);
			try {
				FileUtils.copyURLToFile(new URL(label_url), new File(fileUrl));
				apiLabelResponse.setRelativePath(relativePath + pdfName);
			} catch (Exception e) {
				LOGGER.error("kts.copy.url.to.file.exception", e);
			}
			apiLabelResponse.setLabelPath(label_url);
			apiLabelResponse.setLabelFormat(LabelFormat.PDF.getFormat());
			return apiLabelResponse;
		} catch (Exception e) {
			LOGGER.error("kts.label.exception", e);
			return new ApiLabelResponse(trackNumber, null);
		}
	}
}